import os

from flask import Blueprint, url_for, request, jsonify, current_app, send_from_directory
from flask_jwt_extended import create_access_token, jwt_required
from marshmallow import ValidationError
from werkzeug.utils import secure_filename

from application import db
from werkzeug.security import generate_password_hash, check_password_hash

from application.common.file_helper import allowed_pic_file, get_root_path
from application.users.models import Users
from application.users.schemas import UsersSchema

users_api = Blueprint('users_api', __name__)


# 获取users列表
@users_api.route('/', methods=['GET'])
@jwt_required
def index():
    get_users = Users.query.all()
    users_schema = UsersSchema(many=True)
    # 将model对象转换成一个python列表
    users = users_schema.dump(get_users)
    return jsonify({'status_code': 200, 'status_message': 'successful', 'data': users})


@users_api.route('/<int:user_id>', methods=['GET'])
def get_user_by_id(user_id):
    get_user = Users.query.get(user_id)
    users_schema = UsersSchema()
    user = users_schema.dump(get_user)
    return jsonify({'status_code': 200, 'status_message': 'successful', 'data': user})


@users_api.route('/', methods=['POST'])
def create_user():
    json_data = request.get_json()
    if 'password' not in json_data:
        raise ValidationError(message='password required')
    json_data['password'] = generate_password_hash(json_data['password'])
    users_schema = UsersSchema()
    # 将json数据转换成model对象
    user = users_schema.load(json_data)
    db.session.add(user)
    db.session.commit()
    user = users_schema.dump(user)
    return jsonify({'status_code': 200, 'status_message': 'successful', 'data': user})


@users_api.route('/<int:user_id>', methods=['PUT'])
def update_user(user_id):
    json_data = request.get_json()
    get_user = Users.query.get(user_id)
    if 'fullname' in json_data:
        get_user.fullname = json_data['fullname']
    if 'password' in json_data:
        get_user.password = generate_password_hash(json_data['password'])
    if 'status' in json_data:
        get_user.status = json_data['status']
    if 'current_listen_status' in json_data:
        get_user.current_listen_status = json_data['current_listen_status']

    db.session.add(get_user)
    db.session.commit()

    users_shcema = UsersSchema()
    user = users_shcema.dump(get_user)
    return jsonify({'status_code': 200, 'status_message': 'successful', 'data': user})


@users_api.route('/<int:user_id>', methods=['DELETE'])
def remove_user(user_id):
    user = Users.query.get(user_id)
    db.session.delete(user)
    db.session.commit()
    return jsonify({'status_code': 200, 'status_message': 'successful'})


@users_api.route('/login', methods=['POST'])
def login():
    json_data = request.get_json()
    username = json_data['username']
    user = Users.query.filter_by(username=username).first()
    if user:
        password = json_data['password']
        if check_password_hash(user.password, password):
            access_token = create_access_token(identity=username)
            return jsonify({'status_code': 200, 'status_message': 'login successful', 'access_token': access_token})
    return jsonify({'status_code': 403, 'status_message': 'username or password error'})


# 访问图片
@users_api.route('/avatar/<string:filename>', methods=['GET'])
def get_avatar(filename):
    file_path = os.path.join(get_root_path(current_app), current_app.config['UPLOAD_PATH'])
    return send_from_directory(file_path, filename)


# 添加、修改用户头像
@users_api.route('/avatar/<int:user_id>', methods=['POST'])
def update_avatar(user_id):
    get_user = Users.query.get_or_404(user_id)
    # 获取上传的文件流
    file = request.files['avatar']
    # 验证图片格式
    if not allowed_pic_file(file.content_type):
        return jsonify({'status_code': 200, 'status_message': 'This img format is not supported'})
    # 对图片文件名进行安全加密
    if get_user:
        filename = secure_filename(file.filename)
        # 保存文件
        file.save(os.path.join(current_app.config['UPLOAD_PATH'], filename))
        # 生成图片链接
        avatar_url = url_for('users_api.get_avatar', filename=filename, _external=True)
        get_user.avatar = avatar_url
        db.session.add(get_user)
        db.session.commit()

        user_schema = UsersSchema()
        user = user_schema.dump(get_user)
        return jsonify({'status_code': 200, 'status_message': 'avatar update successful', 'data': user})
